#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
using namespace std;


class TextQuery
{
public:
    TextQuery(){
        _lines.reserve(107);
    }

    void readFile(const string filename);
    void query(const string & word);//
    void dealLine(string & line);
private:
    //......
    //_lines存的是一行一行的内容
    //查找到单词后需要输出改行的全部内容
    vector<string> _lines;//O(1)

    //单词和行号
    map<string, set<int> > _wordNumbers;//the the

    //单词和词频
    map<string, int> _dict;//
};

void TextQuery::readFile(const string filename){
        ifstream ifs(filename);
        if(!ifs){
            cerr << "ifs open file fail" << endl;
            return;
        }

        string line;
        size_t lineNumber = 0;
        while(getline(ifs,line)){
            //读一行，就把这行的内容保存到vector
            _lines.push_back(line);

            //对读取的一行的内容进行处理
            dealLine(line);

            istringstream iss(line);
            string word;
            while(iss >> word){
                //统计单词和词频
                ++_dict[word];

                //记录单词和行号
                _wordNumbers[word].insert(lineNumber);
            }
            ++lineNumber;
        }

        ifs.close();
}


void TextQuery::dealLine(string & line){
    //不应该直接舍去与符号连在一起的单词
    //可以用空格替代符号
    for(auto & ch : line){
        if(!isalpha(ch)){
            ch = ' ';
        }
        else if(isupper(ch))
        {
            ch = tolower(ch);
        }
    }
}

void TextQuery::query(const string & word){
    cout << "----------------" << endl;
    int count = _dict[word];//获取单词出现次数
    cout << word << " occurs " << count
        << (count > 1 ? " times." : " time.")
        << endl;

    auto lines = _wordNumbers[word];
    for(auto & num : lines){
        cout << "(line " << num + 1 << ")" 
            << _lines[num] << endl;
    }

}

//程序测试用例
int main(int argc, char *argv[])
{
    string queryWord("hello");
    TextQuery tq;
    tq.readFile("china_daily.txt");
    tq.query(queryWord);
    return 0;
}
